﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Security.Principal;
using System.Threading;


using Job.Core;
using Job.Core.Module;
using Job.Core.Security;

namespace Job.ManageMember
{
    /// <summary>
    /// User 类。
    /// </summary>
    [Serializable]
    public class User : Business<Int32, User>, IPrincipal, IIdentity
    {

        #region Properties

        /// <summary>
        /// 用户名。
        /// </summary>
        public String UserName { get; set; }

        /// <summary>
        /// 密码。
        /// </summary>
        public String Password { get; set; }

        /// <summary>
        /// 角色ID。
        /// </summary>
        public Int32 RoleID { get; set; }

        private Role role;
        /// <summary>
        /// 角色。
        /// </summary>
        public Role Role
        {
            get
            {
                if (role == null && RoleID != 0)
                    role = Role.Load(RoleID);

                return role;
            }            
        }

        /// <summary>
        /// 帐户状态。
        /// </summary>
        public UserStatus Status { get; set; }

        /// <summary>
        /// 邮箱。
        /// </summary>
        public String Email { get; set; }

        /// <summary>
        /// 建立时间。
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 登录次数。
        /// </summary>
        public Int32 LoginCount { get; set; }

        /// <summary>
        /// 登录错误次数。
        /// </summary>
        public Int32 LoginError { get; set; }

        /// <summary>
        /// 登录错误时间。
        /// </summary>
        public DateTime? LoginErrorTime { get; set; }

        /// <summary>
        /// 登录错误IP。
        /// </summary>
        public String LoginErrorIP { get; set; }

        /// <summary>
        /// 当前登录时间。
        /// </summary>
        public DateTime? CurrentLoginTime { get; set; }

        /// <summary>
        /// 当前登录IP。
        /// </summary>
        public String CurrentLoginIP { get; set; }

        /// <summary>
        /// 上次登录时间。
        /// </summary>
        public DateTime? LastLoginTime { get; set; }

        /// <summary>
        /// 上次登录IP。
        /// </summary>
        public String LastLoginIP { get; set; }        

        #endregion

        #region Static

        /// <summary>
        /// 获取所有 User 列表。
        /// </summary>
        public static IEnumerable<User> GetUsers()
        {
            return MemberService.Repository.GetUsers();
        }

        /// <summary>
        /// 获取分页 User 列表。
        /// </summary>
        public static IEnumerable<User> GetUsers(int pageIndex, int pageSize, out int count)
        {
            return MemberService.Repository.GetUsers(pageIndex, pageSize, out count);
        }

        /// <summary>
        /// 根据用户名加载用户对象。
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static User Load(string name)
        {
            return MemberService.Repository.GetUser(name);
        }        

        #endregion

        #region Membership

        private static readonly Aes aes = new Aes("!ruson523$", "$ruson523!");

        /// <summary>
        /// 更改用户密码。
        /// </summary>
        /// <param name="oldPassword">旧密码。</param>
        /// <param name="newPassword">新密码。</param>
        /// <returns></returns>
        public virtual bool ModifyPassword(string oldPassword, string newPassword)
        {
            string ff = aes.Encrypt(oldPassword);
            if (aes.Encrypt(oldPassword) != Password)
                return false;

            Password = aes.Encrypt(newPassword);
            return Update();
        }

        /// <summary>
        /// 加密密码。
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public virtual string EncryptPassword(string data)
        {
            return aes.Encrypt(data);
        }

        /// <summary>
        /// 解密密码。
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public virtual string DecryptPassword(string data)
        {
            return aes.Decrypt(data);
        }

        /// <summary>
        /// 用于登录时引发的事件。
        /// </summary>
        public static EventHandler<LoginEventArgs> Logining;

        protected void OnLogining(LoginStatus status)
        {
            if (Logining != null)
                Logining(this, new LoginEventArgs(status));
        }

        /// <summary>
        /// 用户登录。
        /// </summary>
        public static User Login(string name, string password, string ip, out LoginStatus status)
        {
            User user = null;

            //用户密码为空。
            if (string.IsNullOrEmpty(name))
            {
                status = LoginStatus.InvalidUser;
                return null;
            }

            if (string.IsNullOrEmpty(password))
            {
                status = LoginStatus.InvalidPassword;
                return null;
            }

            user = Load(name);

            //用户不存在。
            if (user == null)
            {
                status = LoginStatus.InvalidUser;
                return null;
            }

            //判断用户是否锁定。
            if (user.Status == UserStatus.锁定)
            {
                status = LoginStatus.Locked;
                user.OnLogining(status);
                return user;
            }

            user = (User)user.Clone();

            //验证密码。
            if (aes.Encrypt(password) != user.Password)
            {
                status = LoginStatus.InvalidPassword;
                user.LoginError++;
                user.LoginErrorTime = DateTime.Now;
                user.LoginErrorIP = ip;
                user.Update();
                user.OnLogining(status);
                return user;
            }

            //更新登录数据。
            user.LoginCount++;
            user.LoginError = 0;
            user.LastLoginIP = user.CurrentLoginIP;
            user.CurrentLoginIP = ip;
            user.LastLoginTime = user.CurrentLoginTime;
            user.CurrentLoginTime = DateTime.Now;
            user.Update();

            status = LoginStatus.Success;            
            return user;
        }

        #endregion

        #region Overrides

        protected override User DataLoad(Int32 id)
        {
            return MemberService.Repository.GetUser(id);
        }

        protected override bool DataUpdate()
        {
            return MemberService.Repository.UpdateUser(this);
        }

        protected override bool DataCreate()
        {
            CreateTime = DateTime.Now;
            return MemberService.Repository.CreateUser(this);
        }

        protected override bool DataDelete()
        {
            return MemberService.Repository.DeleteUser(this);
        }

        protected override SearchResult<User> DataSearch(SearchQuery Query)
        {
            return new SearchResult<User>();
        }

        /// <summary>
        /// 有效性验证。
        /// </summary>
        protected override void ValidationRules(DataAction action)
        {
            base.ValidationRules(action);
            if (action == DataAction.Delete) return;

            AddRule(string.IsNullOrEmpty(UserName), new RuleViolation("UserName", "用户名为必填项。"));
            AddRule(string.IsNullOrEmpty(Password), new RuleViolation("Password", "密码为必填项。"));
            AddRule(string.IsNullOrEmpty(Email), new RuleViolation("Email", "邮箱为必填项。"));
        }

        public override string ToString()
        {
            return UserName;
        }

        #endregion

        #region IPrincipal 成员

        public IIdentity Identity
        {
            get { return this; }
        }

        public bool IsInRole(string role)
        {
            return Role.RoleName == role;
        }

        #endregion

        #region IIdentity 成员

        public string AuthenticationType
        {
            get { return "Forms"; }
        }

        public bool IsAuthenticated
        {
            get { return KeyId != 0; }
        }

        public string Name
        {
            get { return UserName; }
        }

        #endregion
    }

    #region LoginEventArgs

    /// <summary>
    /// 登录事件参数。
    /// </summary>
    public class LoginEventArgs : EventArgs
    {
        public LoginStatus Status { get; set; }

        public LoginEventArgs(LoginStatus status)
        {
            Status = status;
        }
    }

    #endregion

}
